﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization.NodeTypeResolvers;

namespace XY_PLC
{
    public interface IXYPLC : IDisposable
    {
        ILogger Logger { get; set; }

        /// <summary>
        /// 是否使用PLC 当第一次连接失败之后默认未使用PLC
        /// </summary>
        bool UsePLC { get; set; }

        /// <summary>
        /// 是否可以重新连接
        /// </summary>
        bool CanReConnect { get; set; }

        bool PLCConnected { get; }

        /// <summary>
        /// 第一步初始化功能载体
        /// </summary>
        public void Initialize(ILogger logger);

        /// <summary>
        /// 第二步加载配置
        /// </summary>
        public void LoadConfig();

        /// <summary>
        /// 第三步连接PLC或者其他1
        /// </summary>
        public ValueTask Connect();

        /// <summary>
        /// 获取所有电源状态
        /// </summary>
        /// <param name="ControlPower">返回ControlPower的数组 True为开 False为关</param>
        /// <returns></returns>
        public ValueTask<bool> GetAllPowerStatus(bool[] ControlPower);

        /// <summary>
        /// 设置所有电源状态
        /// </summary>
        /// <param name="ControlPower"></param>
        /// <returns></returns>
        public ValueTask<bool> SetAllPowerStatus(bool[] ControlPower);

        /// <summary>
        /// 设置单个电源状态
        /// </summary>
        /// <param name="Control"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public ValueTask<bool> SetPowerStatus(int Control, bool status);

        /// <summary>
        /// 获取单个电源状态
        /// </summary>
        /// <param name="Control"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public ValueTask<bool> GetPowerStatus(int Control);

        /// <summary>
        /// 获得电源数量
        /// </summary>
        /// <returns></returns>
        public int GetPowerCount();

        /// <summary>
        /// 获取PLC连接状态
        /// </summary>
        /// <returns></returns>
        public bool GetConnectStatus();

        /// <summary>
        /// 开启或关闭PLC心跳
        /// </summary>
        /// <param name="enable"></param>
        /// <returns></returns>
        public void EnableHeartBeat(bool enable);

        /// <summary>
        /// 设置报警
        /// </summary>
        /// <param name="ErrorCode">协议规定的错误码</param>
        /// <param name="Status">警报开启与关闭</param>
        /// <returns></returns>
        public bool SetAlarm(int ErrorCode, bool Status);

        /// <summary>
        /// 当前是否为UPS供电（即是否整机断电）
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        public bool IsUPSPower(out bool status);

        /// <summary>
        /// 关闭程序需要做的工作
        /// </summary>
        /// <returns></returns>
        public void EndProgress();

        /// <summary>
        /// 重新连接PLC
        /// </summary>
        /// <returns></returns>
        public void ReConnect();

        /// <summary>
        /// 开始运行前的准备工作
        /// </summary>
        public void BeforeStartRunning(Func<IEnumerable<int>> CurrentRunningLayers, int Power);

        /// <summary>
        /// 下电前的准备工作
        /// </summary>
        public void BeforePowerDown(
            Func<IEnumerable<int>> CurrentRunningLayers,
            Func<IEnumerable<int>> AllRunningLayers
        );

        /// <summary>
        /// 归一化轮询
        /// </summary>
        /// <returns></returns>
        public IEnumerable<(int Layer, string ErrorCode)> PrimaryPolling();

        /// <summary>
        /// PLC使能状态更新，更新关于PLC使能失败通知
        /// </summary>
        event Action<bool> UsePLCStatusChanged;
    }
}
